/**
 * Copyright (C) 2017 ilikeshatang. All rights reserved.
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.wetao.lib_common.view.voicerecorder;

import android.content.Context;
import android.media.MediaRecorder;
import android.os.Build;
import android.os.Handler;
import android.os.SystemClock;
import android.text.TextUtils;
import android.util.Log;

import androidx.annotation.RequiresApi;

import java.io.File;
import java.io.IOException;
import java.util.Date;

/**
 * desc:   声音录制类
 * author: wangshanhai
 * email: ilikeshatang@gmail.com
 * date: 2017/10/30 18:36
 */
public class VoiceRecorder {

    public static final int VOICE_RECORDER_IDE = 6001;
    public static final int VOICE_RECORDER_START = 6002;
    public static final int VOICE_RECORDER_PAUSE = 6003;
    public static final int VOICE_RECORDER_COMPLETE = 6004;
    MediaRecorder recorder;

    private int voiceRecorderStatus = VOICE_RECORDER_IDE;

    static final String EXTENSION = ".amr";

    private boolean isRecording = false;
    private long startTime;
    private String voiceFilePath = null;
    private String voiceFileName = null;
    private File file;
    private Handler handler;

    private long pauseStartTime = 0;
    private long pauseTime = 0;

    private String examinationId;
    private long studentId;
    private long questionId;

    private boolean isCustomNamingFile =false;

    public VoiceRecorder(Handler handler) {
        this.handler = handler;
    }

    /**
     * start recording to the file
     *
     * @return string
     */
    public String startRecording(Context appContext) {
        file = null;
        try {
            // need to create recorder every time, otherwise, will got exception
            // from setOutputFile when try to reuse
            if (recorder != null) {
                recorder.release();
                recorder = null;
            }
            recorder = new MediaRecorder();
            recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
//            recorder.setOutputFormat(MediaRecorder.OutputFormat.RAW_AMR);
//            recorder.setAudioEncoder(MediaRecorder.OutputFormat.AMR_NB);
            recorder.setOutputFormat(MediaRecorder.OutputFormat.AAC_ADTS); //设置输入格式 3gp
            recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
            recorder.setAudioChannels(1); // MONO
            recorder.setAudioSamplingRate(44100); // 8000Hz
            recorder.setAudioEncodingBitRate(64); // seems if change this to
            // 128, still got same file
            // size.
            // one easy way is to use temp file
            // file = File.createTempFile(PREFIX + userId, EXTENSION,
            // User.getVoicePath());

            if(!isCustomNamingFile){
                //默认命名是用时间戳0, 15位
//                voiceFileName = getVoiceFileName(System.currentTimeMillis() + "");
            }

            file = new File(voiceFilePath);
            if(file.exists()) {
                file.delete();
            }
            recorder.setOutputFile(file.getAbsolutePath());
            recorder.prepare();
            setRecorderStatus(VOICE_RECORDER_START);
            isRecording = true;
            recorder.start();
        } catch (IOException e) {
            Log.e("voice", "prepare() failed");
        }
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {

                    while (voiceRecorderStatus == VOICE_RECORDER_START || voiceRecorderStatus == VOICE_RECORDER_PAUSE) {
                        /**
                         * 监听音量，改变录音显示icon
                         */
                        if (voiceRecorderStatus == VOICE_RECORDER_START) {
                            android.os.Message msg = new android.os.Message();
                            msg.what = VoiceRecorderView.HANDLER_VOLUME;
                            msg.arg1 = recorder.getMaxAmplitude() * 13 / 0x7FFF;
                            int seconds = (int) (new Date().getTime() - startTime - pauseTime);
                            msg.arg2 = seconds;
                            handler.sendMessage(msg);
                        } else if (voiceRecorderStatus == VOICE_RECORDER_PAUSE) {

                        }

                        SystemClock.sleep(100);
                    }
//                    while (isRecording) {
//                        /**
//                         * 监听音量，改变录音显示icon
//                         */
//                        android.os.Message msg = new android.os.Message();
//                        msg.what = VoiceRecorderView.HANDLER_VOLUME;
//                        msg.arg1 = recorder.getMaxAmplitude() * 13 / 0x7FFF;
//                        int seconds = (int) (new Date().getTime() - startTime) / 1000;
//                        msg.arg2 = seconds;
//                        handler.sendMessage(msg);
//                        SystemClock.sleep(100);
//                    }
                } catch (Exception e) {
                    // from the crash report website, found one NPE crash from
                    // one android 4.0.4 htc phone
                    // maybe handler is null for some reason
                    Log.e("voice", e.toString());
                }
            }
        }).start();
        startTime = new Date().getTime();
        Log.d("voice", "start voice recording to file:" + file.getAbsolutePath());
        return file == null ? null : file.getAbsolutePath();
    }


    @RequiresApi(api = Build.VERSION_CODES.N)
    public void pauseRecording() {
        if (recorder != null) {
            voiceRecorderStatus = VOICE_RECORDER_PAUSE;
            pauseStartTime = new Date().getTime();
            recorder.pause();
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.N)
    public void resumeRecording() {
        if (recorder != null) {
            voiceRecorderStatus = VOICE_RECORDER_START;
            pauseTime = new Date().getTime() - pauseStartTime + pauseTime;
            recorder.resume();
        }
    }

    /**
     * stop the recoding
     * seconds of the voice recorded
     */
    public void discardRecording() {
        if (recorder != null) {
            try {
                recorder.stop();
                recorder.release();
                recorder = null;
                if (file != null && file.exists() && !file.isDirectory()) {
                    file.delete();
                }
            } catch (IllegalStateException e) {
            } catch (RuntimeException e) {
            }
            isRecording = false;
        }
    }

    public int stopRecoding() {
        if (recorder != null) {
            isRecording = false;
            recorder.stop();
            recorder.release();
            recorder = null;

            if (file == null || !file.exists() || !file.isFile()) {
                return EMError.FILE_INVALID;
            }
            if (file.length() == 0) {
                file.delete();
                return EMError.FILE_INVALID;
            }
            int seconds = (int) (new Date().getTime() - startTime) / 1000;
            Log.d("voice", "voice recording finished. seconds:" + seconds + " file length:" + file.length());
            return seconds;
        }
        return 0;
    }

    protected void finalize() throws Throwable {
        super.finalize();
        if (recorder != null) {
            recorder.release();
        }
    }

    private String getVoiceFileName(String uid) {
        //return this.examinationId + "_" + this.studentId + "_" + this.questionId + EXTENSION;
        return "unique" + EXTENSION;
    }

    public boolean isRecording() {
        return isRecording;
    }

    public String getVoiceFilePath() {
        return voiceFilePath;
    }

    public String getVoiceFileName() {
        return voiceFileName;
    }




    /**
     * 判断是否存在缓存文件夹
     *
     * @return
     */
    public boolean isDirExist() {
        if (TextUtils.isEmpty(PathUtil.pathPrefix)) {
            return false;
        } else {
            return true;
        }
    }

    /**
     * 自定义音频文件命名
     *
     * @param voiceFileName
     */
    public void setVoiceFileName(String voiceFileName) {
        this.voiceFileName = voiceFileName+EXTENSION;
    }

    public void setIds(int examinationId, long studentId, long questionId) {
        this.examinationId = examinationId + "";
        this.studentId = studentId;
        this.questionId = questionId;
    }
    public void setIds(String examinationId, long studentId, long questionId) {
        this.examinationId = examinationId + "";
        this.studentId = studentId;
        this.questionId = questionId;
    }

    public int getRecordStatus() {
        return voiceRecorderStatus;
    }

    public void setRecorderStatus(int voiceRecorderStatus) {
        this.voiceRecorderStatus = voiceRecorderStatus;
    }

    public void setVoiceFilePath(String voiceFilePath) {
        this.voiceFilePath = voiceFilePath;
    }
}
